/**
 * 对象工具函数
 */

/**
 * 深拷贝对象
 * @param {any} obj - 要拷贝的对象
 * @returns {any} 深拷贝后的对象
 */
export function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }
  if (obj instanceof Date) {
    return new Date(obj);
  }
  if (obj instanceof Array) {
    return obj.map(item => deepClone(item));
  }
  if (typeof obj === 'object') {
    const clonedObj = {};
    for (const key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) {
        clonedObj[key] = deepClone(obj[key]);
      }
    }
    return clonedObj;
  }
  return obj;
}

/**
 * 对象合并
 * @param {Object} target - 目标对象
 * @param {...Object} sources - 源对象
 * @returns {Object} 合并后的对象
 */
export function merge(target, ...sources) {
  if (!target || typeof target !== 'object') {
    target = {};
  }

  sources.forEach(source => {
    if (!source || typeof source !== 'object') {
      return;
    }

    for (const key in source) {
      if (source.hasOwnProperty(key)) {
        if (
          source[key] &&
          typeof source[key] === 'object' &&
          !Array.isArray(source[key])
        ) {
          target[key] = merge(target[key] || {}, source[key]);
        } else {
          target[key] = source[key];
        }
      }
    }
  });

  return target;
}

/**
 * 获取对象属性值（支持路径）
 * @param {Object} obj - 对象
 * @param {string} path - 属性路径，如 'a.b.c'
 * @param {any} defaultValue - 默认值
 * @returns {any} 属性值
 */
export function get(obj, path, defaultValue) {
  if (!obj || typeof obj !== 'object') {
    return defaultValue;
  }

  const keys = path.split('.');
  let result = obj;

  for (const key of keys) {
    if (
      result === null ||
      result === undefined ||
      !result.hasOwnProperty(key)
    ) {
      return defaultValue;
    }
    result = result[key];
  }

  return result;
}

/**
 * 设置对象属性值（支持路径）
 * @param {Object} obj - 对象
 * @param {string} path - 属性路径，如 'a.b.c'
 * @param {any} value - 值
 * @returns {Object} 设置后的对象
 */
export function set(obj, path, value) {
  if (!obj || typeof obj !== 'object') {
    return obj;
  }

  const keys = path.split('.');
  const lastKey = keys.pop();
  let current = obj;

  for (const key of keys) {
    if (!current[key] || typeof current[key] !== 'object') {
      current[key] = {};
    }
    current = current[key];
  }

  current[lastKey] = value;
  return obj;
}

/**
 * 删除对象属性（支持路径）
 * @param {Object} obj - 对象
 * @param {string} path - 属性路径，如 'a.b.c'
 * @returns {boolean} 是否删除成功
 */
export function unset(obj, path) {
  if (!obj || typeof obj !== 'object') {
    return false;
  }

  const keys = path.split('.');
  const lastKey = keys.pop();
  let current = obj;

  for (const key of keys) {
    if (!current[key] || typeof current[key] !== 'object') {
      return false;
    }
    current = current[key];
  }

  return delete current[lastKey];
}

/**
 * 检查对象是否为空
 * @param {Object} obj - 对象
 * @returns {boolean} 是否为空
 */
export function isEmpty(obj) {
  if (!obj || typeof obj !== 'object') {
    return true;
  }
  return Object.keys(obj).length === 0;
}

/**
 * 对象键值对交换
 * @param {Object} obj - 对象
 * @returns {Object} 键值对交换后的对象
 */
export function invert(obj) {
  if (!obj || typeof obj !== 'object') {
    return {};
  }

  const result = {};
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      result[obj[key]] = key;
    }
  }
  return result;
}

/**
 * 对象过滤
 * @param {Object} obj - 对象
 * @param {Function} predicate - 过滤函数
 * @returns {Object} 过滤后的对象
 */
export function pickBy(obj, predicate) {
  if (!obj || typeof obj !== 'object') {
    return {};
  }

  const result = {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key) && predicate(obj[key], key)) {
      result[key] = obj[key];
    }
  }
  return result;
}

/**
 * 选择对象属性
 * @param {Object} obj - 对象
 * @param {Array|string} keys - 要选择的键
 * @returns {Object} 选择后的对象
 */
export function pick(obj, keys) {
  if (!obj || typeof obj !== 'object') {
    return {};
  }

  const keyArray = Array.isArray(keys) ? keys : [keys];
  const result = {};

  keyArray.forEach(key => {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      result[key] = obj[key];
    }
  });

  return result;
}

/**
 * 排除对象属性
 * @param {Object} obj - 对象
 * @param {Array|string} keys - 要排除的键
 * @returns {Object} 排除后的对象
 */
export function omit(obj, keys) {
  if (!obj || typeof obj !== 'object') {
    return {};
  }

  const keyArray = Array.isArray(keys) ? keys : [keys];
  const result = { ...obj };

  keyArray.forEach(key => {
    delete result[key];
  });

  return result;
}

/**
 * 对象比较
 * @param {Object} obj1 - 对象1
 * @param {Object} obj2 - 对象2
 * @returns {boolean} 是否相等
 */
export function isEqual(obj1, obj2) {
  if (obj1 === obj2) {
    return true;
  }
  if (obj1 == null || obj2 == null) {
    return false;
  }
  if (typeof obj1 !== typeof obj2) {
    return false;
  }

  if (typeof obj1 !== 'object') {
    return obj1 === obj2;
  }

  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);

  if (keys1.length !== keys2.length) {
    return false;
  }

  for (const key of keys1) {
    if (!keys2.includes(key)) {
      return false;
    }
    if (!isEqual(obj1[key], obj2[key])) {
      return false;
    }
  }

  return true;
}
